package sg.edu.nus.iss.vmcs.customer;

import sg.edu.nus.iss.vmcs.store.*;
import sg.edu.nus.iss.vmcs.util.VMCSException;

/**
* This class represents the control object that manages the giving of change to
* the customer. 
*
*/
public class ChangeGiver {

	private TransactionController transCtrl;

/**
 * This constructor creates a new instance of the ChangeGiver. It receives
 * the reference for TransactionController as a parameter.
 * @param tctrl Transaction Controller
 * @see TransactionController
 */	
	public ChangeGiver(TransactionController tctrl) {
		transCtrl = tctrl;
	}

/**
 * This operation is used to reset the Refund/Change Tray Display on the Customer
 * Panel.
 */	
	public void resetChange(){
		transCtrl.getCustomerPanel().getCollectCoin().setValue("0" + " C");
	}

/**
 * This operation manages the issuing of change to the Customer.
 * @param changeRequired Integer Value
 * @return boolean state
 * @throws VMCSException Exception during issuing of change / refund
 */	
	public boolean giveChange(int changeRequired) throws VMCSException{
		int changeGiven,qty ,value,max,numOfCoins; 
		changeGiven = 0;
		Store store = transCtrl.getStoreController().getStore(Store.CASH);
		StoreItem[] storeItems = store.getItems();
		for(int i=storeItems.length -1; i >= 0; i--){
			StoreItem storeItem = storeItems[i];
			Coin coin = (Coin)storeItem.getContent();
			qty = storeItem.getQuantity();
			value = coin.getValue();
			max = (int)Math.floor(changeRequired / value);
			if( max > qty)
				numOfCoins = qty;
			else
				numOfCoins = max;
			
			if (numOfCoins > 0)
				try {
					transCtrl.getMainController().getMachineryController().giveChange(i, numOfCoins);
				} catch (VMCSException e) {
					transCtrl.terminateFault(this);
					throw new VMCSException("Change",e.getMessage());
				}
			
			changeGiven +=numOfCoins * value;
			changeRequired = changeRequired - numOfCoins * value;
			if(changeRequired == 0)
				break;
		}
		
		transCtrl.getCustomerPanel().getCollectCoin().setValue(String.valueOf(changeGiven) + " C");
		
		if(changeRequired>0)
			transCtrl.getCustomerPanel().getNoChangeAvail().setState(true);
		
		return true;
	}

/**
 * This operation is used to display the appropriate message on the No Change 
 * Available Display depending on the current change availability.
 */
	public void displayChangeStatus(){
		//????how to check change availibility
		boolean noChange = true;
		CashStore cashStore = (CashStore)transCtrl.getStoreController().getStore(Store.CASH);
		for(int i=0;i<=cashStore.getStoreSize()-1;i++){
			CashStoreItem cashStoreItem = (CashStoreItem)cashStore.getStoreItem(i);
			if(cashStoreItem.getQuantity()>0){
				noChange = false;
				break;
			}
		}
		transCtrl.getCustomerPanel().getNoChangeAvail().setState(noChange);
	}
}
